using BackOffice.Application.DTOs;
using BackOffice.Application.Services;
using Backoffice.Application.Common;
using Backoffice.Domain.Entities.App;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Backoffice.Domain.Repositories;

namespace BackOffice.Application.Services
{
    public class MenuService : IMenuService
    {
        private readonly IRepository<AppMenu> _menuRepo;

        public MenuService(IRepository<AppMenu> menuRepo)
        {
            _menuRepo = menuRepo;
        }

        public async Task<ApiResult> CreateMenuAsync(CreateMenuDto createMenuDto)
        {
            var menus = await _menuRepo.GetAllAsync();
            var exists = menus.Any(m => m.Url == createMenuDto.Url);
            if (exists)
            {
                return ApiResult.Fail("菜单路径已存在", 3001);
            }

            var menu = new AppMenu(createMenuDto.Name, createMenuDto.Url, createMenuDto.ParentId, createMenuDto.Order);
            await _menuRepo.CreateAsync(menu);
            return ApiResult.Success(menu, "创建菜单成功");
        }

        public async Task<ApiResult> UpdateMenuAsync(Guid menuId, UpdateMenuDto updateMenuDto)
        {
            var menu = await _menuRepo.GetByIdAsync(menuId);
            if (menu == null)
            {
                return ApiResult.Fail("菜单未找到", 3002);
            }

            menu.UpdateInfo(updateMenuDto.Name, updateMenuDto.Url, updateMenuDto.Order);
            await _menuRepo.UpdateAsync(menu);
            return ApiResult.Success(menu, "更新菜单成功");
        }

        public async Task<ApiResult> DeleteMenuAsync(Guid menuId)
        {
            var menu = await _menuRepo.GetByIdAsync(menuId);
            if (menu == null)
            {
                return ApiResult.Fail("菜单未找到", 3002);
            }

            await _menuRepo.DeleteAsync(menuId);
            return ApiResult.Success(null, "删除菜单成功");
        }

        public async Task<ApiResult> GetMenuTreeAsync()
        {
            var menus = await _menuRepo.GetAllAsync();
            var menuTree = BuildMenuTree(menus, null);
            return ApiResult.Success(menuTree, "获取菜单树成功");
        }

        public async Task<ApiResult> MoveMenuAsync(Guid menuId, Guid newParentId, int newOrder)
        {
            var menu = await _menuRepo.GetByIdAsync(menuId);
            if (menu == null)
            {
                return ApiResult.Fail("菜单未找到", 3002);
            }

            menu.UpdateParentAndOrder(newParentId, newOrder);
            await _menuRepo.UpdateAsync(menu);
            return ApiResult.Success(menu, "移动菜单成功");
        }

        private IEnumerable<AppMenu> BuildMenuTree(IEnumerable<AppMenu> menus, Guid? parentId)
        {
            return menus.Where(m => m.ParentId == parentId)
                        .Select(m => m.Clone());
        }
    }
}